package cn.pconline.officialclub.service;

import cn.pconline.autoclub.entity.DynaImage;
import cn.pconline.autoclub.entity.DynaInfo;
import cn.pconline.autoclub.service.DynaIndexService;
import cn.pconline.autoclub.service.EffectiveDynaService;
import cn.pconline.autoclub.util.DateUtils;
import cn.pconline.autoclub.util.Pager;
import cn.pconline.autoclub.util.dyna.AbstractDyna;
import cn.pconline.autoclub.util.dyna.CommentDyna;
import cn.pconline.officialclub.entity.OClubDyna;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.gelivable.dao.Mid;
import org.gelivable.dao.SqlBuilder;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 官方车友会动态相关 <br/>官方车友会发动态（删除动态）会同步到民间车友会（单向同步）
 *
 * @author <a href="mailto:chensy0203@163.com">chensy</a>
 */
public class ODynaService extends ServiceKit {

    public static final int ORDER_LAST_POST_DATE = 1; //回复时间排序
    public static final int ORDER_CREATE_DATE = 0; //发表时间排序
    @Autowired
    private EffectiveDynaService dynaService;
    @Autowired
    private DynaIndexService dynaIndexService;

    /**
     * 获取某一车友会动态
     *
     * @param dynaInfoId
     * @param oClubId
     * @return
     */
    public OClubDyna findClubDyna(long dynaInfoId, long oClubId) {
        return findById(OClubDyna.class, oClubId, new Mid(oClubId, dynaInfoId));
    }

    /**
     * 创建车友会动态的索引记录
     *
     * @param dynaInfo
     * @return
     */
    public long createClubDyna(DynaInfo dynaInfo, long oClubId) {
        OClubDyna dyna = new OClubDyna();
        dyna.setOClubId(oClubId);
        dyna.setCreateAt(dynaInfo.getCreateAt() == null ? DateUtils.getNow() : dynaInfo.getCreateAt());
        dyna.setCreateDate(dynaInfo.getCreateDate());
        dyna.setDynaInfoId(dynaInfo.getDynaInfoId());
        dyna.setForumId(dynaInfo.getForumId());
        dyna.setLastPostAt(dynaInfo.getLastPostAt());
        dyna.setPick(dynaInfo.getPick());
        dyna.setPostCount(dynaInfo.getPostCount());
        dyna.setRecommend(dynaInfo.getRecommend());
        dyna.setStatus(dynaInfo.getStatus());
        dyna.setType(dynaInfo.getType());
        dyna.setCreateBy(dynaInfo.getCreateBy());
        return geliDao.create(dyna);
    }

    /**
     * 根据动态ID分页查询动态列表（包括图片也会查出来），按order排序
     *
     * @param oClubId
     * @param pick
     * @param pageNo
     * @param pageSize
     * @param orderType
     * @param type
     * @return 无查询结果返回NULL
     */
    public Pager<DynaInfo> getDynaListByClubId(long oClubId, Boolean isPick, Boolean isTop, int pageNo, int pageSize, int orderType, Integer... type) {
        SqlBuilder sql = new SqlBuilder();
        String selectSql = "select dyna_info_id,create_date ";
        sql.appendSql(selectSql);
        sql.appendSql(" from ").appendSql(getTableName(OClubDyna.class, oClubId));
        sql.appendSql(" where o_club_id = ").appendValue(oClubId);
        sql.appendSql(" and status !=").appendValue(DynaInfo.STATUS_DELETE);
        if (isPick != null) {
            sql.appendSql(" and pick = ").appendValue(isPick ? 1 : 0);
        }
        if (type != null && type.length > 0) {
            sql.appendSql(" and type in ").appendValues(type);
        }
        String orderSql = null;
        if (isTop == null) {
            if (orderType == ORDER_LAST_POST_DATE) {
                orderSql = " order by last_post_at desc";
            }
            if (orderType == ORDER_CREATE_DATE) {
                orderSql = " order by create_date desc";
            }
        } else if (isTop) {
            sql.appendSql(" and is_top = ").appendValue(OClubDyna.TOP_YES);
            if (orderType == ORDER_LAST_POST_DATE) {
                orderSql = " order by top_date desc,last_post_at desc";
            }
            if (orderType == ORDER_CREATE_DATE) {
                orderSql = " order by top_date desc,create_date desc";
            }
        } else {
            sql.appendSql(" and is_top = ").appendValue(OClubDyna.TOP_NO);
            if (orderType == ORDER_LAST_POST_DATE) {
                orderSql = " order by last_post_at desc";
            }
            if (orderType == ORDER_CREATE_DATE) {
                orderSql = " order by create_date desc";
            }
        }
        return dynaService.getDynaListBySql(sql, orderSql, selectSql, pageNo, pageSize);
    }

    /**
     * 根据动态ID分页查询动态列表（包括图片也会查出来）
     *
     * @param oClubId
     * @param pageNo
     * @param pageSize
     * @param orderType
     * @param types
     * @return 无查询结果返回NULL
     */
    public Pager<DynaInfo> getDynaListByClubId(long oClubId, int pageNo, int pageSize, int orderType, Integer... types) {
        return getDynaListByClubId(oClubId, null, null, pageNo, pageSize, orderType, types);
    }

    /**
     * 查前几条置顶的动态，按最新的发布时间排序
     *
     * @param oClubId
     * @param num
     * @return 无查询结果返回NULL
     */
    public Pager<DynaInfo> getTopDynaListByClubId(long oClubId, int num) {
        //这里其实不需要Pager，查多了总数。考虑到代码重用，查多一次，关系不太大
        return getDynaListByClubId(oClubId, null, true, 1, num, ORDER_CREATE_DATE);
    }

    /**
     * 根据动态ID分页查询动态列表（包括图片也会查出来）
     *
     * @param oClubId
     * @param pageNo
     * @param pageSize
     * @param orderType
     * @return 无查询结果返回NULL
     */
    public Pager<DynaInfo> getTopicDynaListByClubId(long oClubId, int pageNo, int pageSize, int orderType) {
        return getDynaListByClubId(oClubId, null, false, pageNo, pageSize, orderType, DynaInfo.getTopicType());
    }

    /**
     * 根据车友会ID分布查询说说列表，按最新的发布时间排序
     *
     * @param oClubId
     * @param pageNo
     * @param pageSize
     * @return
     */
    public Pager<DynaInfo> getCommentDynaListByClubId(long oClubId, int pageNo, int pageSize) {
        return getDynaListByClubId(oClubId, null, null, pageNo, pageSize, ORDER_CREATE_DATE, DynaInfo.TYPE_COMMENT);
    }

    /**
     * 根据动态ID分页查询动态列表（包括图片也会查出来）
     *
     * @param oClubId
     * @param pageNo
     * @param pageSize
     * @param orderType
     * @return 无查询结果返回NULL
     */
    public Pager<DynaInfo> getPickTopicDynaListByClubId(long oClubId, int pageNo, int pageSize, int orderType) {
        return getDynaListByClubId(oClubId, true, null, pageNo, pageSize, orderType, DynaInfo.getTopicType());
    }

    /**
     * 根据用户ID分页查询动态列表（包括图片也会查出来），按最新的发布时间排序
     *
     * @param userId
     * @param pageNo
     * @param pageSize
     * @param types
     * @return 无查询结果返回NULL
     */
    private Pager<DynaInfo> getDynaListByUserId(long userId, Boolean isPick, int pageNo, int pageSize, Integer... types) {

        SqlBuilder sql = new SqlBuilder();
        String selectSql = "select dyna_info_id,create_date ";
        sql.appendSql(selectSql);
        sql.appendSql(" from ac_user_dyna_").appendSql(userId % 10 + "");
        sql.appendSql(" where user_id = ").appendValue(userId);
        sql.appendSql(" and status !=").appendValue(DynaInfo.STATUS_DELETE);
        if (isPick != null) {
            sql.appendSql(" and pick = ").appendValue(isPick ? 1 : 0);
        }
        if (types != null && types.length > 0) {
            sql.appendSql(" and type in ").appendValues(types);
        }
        String orderSql = (" order by create_date desc ");
        return dynaService.getDynaListBySql(sql, orderSql, selectSql, pageNo, pageSize);
    }

    /**
     * 根据用户ID分页查询动态列表（包括图片也会查出来），按最新的发布时间排序，所有动态
     *
     * @param userId
     * @param pageNo
     * @param pageSize
     * @return 无查询结果返回NULL
     */
    public Pager<DynaInfo> getDynaListByUserId(long userId, int pageNo, int pageSize) {
        return getDynaListByUserId(userId, null, pageNo, pageSize);
    }

    /**
     * 根据用户ID分页查询动态列表（包括图片也会查出来），帖子列表
     *
     * @param userId
     * @param pageNo
     * @param pageSize
     * @return 无查询结果返回NULL
     */
    public Pager<DynaInfo> getTopicDynaListByUserId(long userId, int pageNo, int pageSize) {
        return getDynaListByUserId(userId, null, pageNo, pageSize, DynaInfo.getTopicType());
    }

    /**
     * 根据用户ID分布查询留言列表
     *
     * @param userId
     * @param pageNo
     * @param pageSize
     * @return
     */
    public Pager<DynaInfo> getCommentDynaListByUserId(long userId, int pageNo, int pageSize) {
        return getDynaListByUserId(userId, null, pageNo, pageSize, DynaInfo.TYPE_COMMENT);
    }

    /**
     * 根据用户ID分页查询动态列表（包括图片也会查出来），精华帖子列表
     *
     * @param userId
     * @param pageNo
     * @param pageSize
     * @return 无查询结果返回NULL
     */
    public Pager<DynaInfo> getPickTopicDynaListByUserId(long userId, int pageNo, int pageSize) {
        return getDynaListByUserId(userId, true, pageNo, pageSize, DynaInfo.getTopicType());
    }

    /**
     * 退出车友会的时候，逻辑删除车友会动态
     *
     * @param oClubId
     * @param userId
     * @return
     */
    public long deleteClubDynaByUserId(long oClubId, long clubId, long userId) {
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql(" select o_club_id,dyna_info_id from ").appendSql(getTableName(OClubDyna.class, oClubId));
        sql.appendSql(" where o_club_id = ").appendValue(oClubId);
        sql.appendSql(" and create_by = ").appendValue(userId);
        List<OClubDyna> list = list(OClubDyna.class, oClubId, sql);
        long count = 0;
        for (OClubDyna d : list) {
            if (clubId > 0) {
                //删除民间车友会的动态
                cn.pconline.autoclub.entity.ClubDyna dyna = dynaService.findClubDynaById(d.getDynaInfoId(), clubId);
                if (dyna != null) {
                    geliDao.delete(dyna, dyna.getId());
                }
            }
            DynaInfo info = dynaService.findDynaInfoById(d.getDynaInfoId(), d.getCreateDate());
            if (info != null) {
                info.setClubId(0);
                dynaService.updateDyna(info, "club_id");
            }
            //删除官方车友会的动态
            count += geliDao.delete(d, d.getId());
        }
        return count;
    }

    /**
     * 帖子删除、审核删除的时候，逻辑删除车友会动态
     *
     * @return
     */
    public long deleteClubDyna(long oClubId, long dynaInfoId) {
        OClubDyna dyna = findClubDyna(dynaInfoId, oClubId);
        int countUpdate = 0;
        if (dyna == null) {
            return countUpdate;
        }
        dyna.setStatus(DynaInfo.STATUS_DELETE);
        countUpdate += geliDao.update(dyna, "status");
        //动态的回复和动态的图片就不用再标记删除了
        return countUpdate;
    }

    /*
     * 批量删除索引（因为论坛同步操作，没有oClubId，所以使用这个方法）
     * 
     * 不更新缓存
     * 
     * 请尽量使用：deleteClubDyna(long clubId, long dynaInfoId)
     *
     * @param dynaInfoId
     * @return
     */
    public long deleteClubDyna(long dynaInfoId) {
        return batchUpdateClubDyna(dynaInfoId, DynaInfo.STATUS_DELETE);
    }

    /**
     * 逻辑恢复动态（同时会更新dynaInfo字段的clubId）
     *
     * @return
     */
    public int rollbackClubDyna(long oClubId, long dynaInfoId) {
        OClubDyna dyna = findClubDyna(dynaInfoId, oClubId);
        int countUpdate = 0;
        if (dyna == null) {
            return countUpdate;
        }
        dyna.setStatus(DynaInfo.STATUS_NORMAL);
        countUpdate += geliDao.update(dyna, "status");
        return countUpdate;
    }

    /*
     * 批量恢复动态（因为论坛同步操作，没有oClubId，所以使用这个方法）
     * 
     * 不更新缓存
     * 
     * 请尽量使用：rollbackClubDyna(long clubId, long dynaInfoId)
     *
     * @param dynaInfoId
     * @return
     */
    public long rollbackClubDyna(long dynaInfoId) {
        return batchUpdateClubDyna(dynaInfoId, DynaInfo.STATUS_NORMAL);
    }

    /*
     * 批量更新动态状态
     * 
     * 不更新缓存
     * 
     * @param dynaInfoId
     * @return
     */
    private long batchUpdateClubDyna(long dynaInfoId, int status) {
        String[] sqls = new String[10];
        for (int i = 0; i < 10; i++) {
            sqls[i] = String.format("update oac_club_dyna_%s set status = %s where dyna_info_id = %s", i, status, dynaInfoId);
        }
        int[] rs = jdbcTemplate.batchUpdate(sqls);
        long update = 0;
        for (int i = 0; i < rs.length; i++) {
            update += rs[i];
        }
        return update;
    }

    /**
     * 修改动态的内容的审核状态
     *
     * @param dynaInfoId
     * @param createDate
     * @param censored
     * @return
     */
    public long censorDynaInfo(DynaInfo info, long oClubId, int censored) {
        if (info == null) {
            return 0;
        }
        OClubDyna clubDyna = findClubDyna(info.getDynaInfoId(), oClubId);
        int status = censored == DynaInfo.CENSORED_PASS ? DynaInfo.STATUS_NORMAL : DynaInfo.STATUS_DELETE;
        if (clubDyna != null) {
            clubDyna.setStatus(status);
            geliDao.update(clubDyna);
        }
        info.setCensored(censored);
        return dynaService.updateDyna(info, "censored");
    }

    /**
     * 获取置顶数量
     *
     * @return
     */
    public int getTopCount(long oClubId) {
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql("select count(1) from ").appendSql(getTableName(OClubDyna.class, oClubId));
        sql.appendSql(" where is_top = ").appendValue(OClubDyna.TOP_YES).appendSql(" and o_club_id = ").appendValue(oClubId);
        sql.appendSql(" and status !=").appendValue(DynaInfo.STATUS_DELETE);
        return count(sql);
    }

    /**
     * 动态置顶
     *
     * @param dynaInfoId
     * @param clubId
     * @return
     */
    public boolean doTop(long dynaInfoId, long clubId) {
        OClubDyna clubDyna = findClubDyna(dynaInfoId, clubId);
        if (clubDyna != null) {
            if (clubDyna.getIsTop() != OClubDyna.TOP_YES) {
                clubDyna.setIsTop(OClubDyna.TOP_YES);
                clubDyna.setTopDate(new Date());
                return geliDao.update(clubDyna, "is_top,top_date") > 0;
            }
            return true;
        }
        return false;

    }

    /**
     * 取消置顶
     *
     * @param dynaInfoId
     * @param clubId
     * @return
     */
    public boolean cancelTop(long dynaInfoId, long clubId) {
        OClubDyna clubDyna = findClubDyna(dynaInfoId, clubId);
        if (clubDyna != null) {
            if (clubDyna.getIsTop() != OClubDyna.TOP_NO) {
                clubDyna.setIsTop(OClubDyna.TOP_NO);
                clubDyna.setTopDate(null);
                return geliDao.update(clubDyna, "is_top,top_date") > 0;
            }
            return true;
        }
        return false;

    }

    /**
     * 按类型统计官方车友会下的动态数
     *
     * @param oClubId
     * @param type new Object[]{1}
     * @return
     */
    public int countClubDynaBy(long oClubId, Object... type) {
        SqlBuilder sqlBuilder = new SqlBuilder();
        sqlBuilder.appendSql("select count(1) from ");
        sqlBuilder.appendSql(getTableName(OClubDyna.class, oClubId));
        sqlBuilder.appendSql(" where o_club_id = ").appendValue(oClubId);
        sqlBuilder.appendSql(" and status = ").appendValue(DynaInfo.STATUS_NORMAL);
        if (type != null && type.length > 0) {
            sqlBuilder.appendSql(" and type in ").appendValues(type);
        }
        return count(sqlBuilder);
    }

    /**
     * 创建动态
     *
     * @param picture
     * @param images 如果没有图片就传空的
     * @return
     */
    private DynaInfo createAbstractDyna(AbstractDyna dyna, long oClubId, int type, List<DynaImage> images) {
        DynaInfo info = new DynaInfo();
        info.setFromType(dyna.getFromType());
        info.setIsOfficialClubDyna(1);//标记为品牌车友会的动态
        info.setCensored(DynaInfo.CENSORED_UNDO);
        info.setClubId(dyna.getClubId());
        info.setContent(dyna.getContent());
        info.setCreateDate(dyna.getCreateDate());
        info.setCreateName(dyna.getCreateName());
        //第一次发表留言动态，上次回复人是自己
        info.setLastPostAt(dyna.getCreateDate());
        info.setLastPostBy(dyna.getCreateBy());
        info.setLastPostName(dyna.getCreateName());
        //设置相关联ID
        info.setTargetId(dyna.getTargetId());
        info.setPostCount(0);
        info.setUpdateAt(dyna.getCreateDate());
        boolean hasPic = (images != null && !images.isEmpty());
        info.setIsPic(hasPic ? DynaInfo.PIC_IS : DynaInfo.PIC_NOT);
        info.setStatus(DynaInfo.STATUS_NORMAL);
        info.setType(type);
        info.setCreateBy(dyna.getCreateBy());
        info.setProvinceId(0);
        info.setCityId(0);
        long infoId = geliDao.create(info);
        if (infoId == 0) {
            log.error("插入动态记录失败！createAbstractDyna[type={}]", type);
            return null;
        }
        if (hasPic) {
            for (DynaImage image : images) {
                image.setDynaInfoId(infoId);
                geliDao.create(image);
            }
        }
        //创建动态索引
        dynaIndexService.createDynaIndex(info);
        //创建车友会动态索引
        createClubDyna(info, oClubId);
        //创建用户动态索引
        dynaService.createUserDyna(info);
        //创建话题相关索引
        String subjectIds = dynaService.createSubjectByDyna(info);
        if (StringUtils.isNotBlank(subjectIds)) {
            info.setSubjectIds(subjectIds);
            dynaService.updateDyna(info, "subject_ids");
            //带话题的说说才需要同步到民间车友会
            if (info.getClubId() > 0) {
                dynaService.createClubDyna(info);
                //不需要发最新动态的消息通知
            }
        }
        return info;
    }

    /**
     * 说说动态 设置clubId大于0时，会同步到民间车友会
     *
     * @param comment
     * @param images 如果没有图片就传空的
     * @return
     */
    public DynaInfo createCommentDyna(CommentDyna comment, long oClubId, List<DynaImage> images) {
        return createAbstractDyna(comment, oClubId, DynaInfo.TYPE_COMMENT, images);
    }

    /**
     * 活动动态
     *
     * @param dyna 设置clubId大于0时，会同步到民间车友会
     * @param images
     * @return
     */
    public DynaInfo createActivityDyna(AbstractDyna dyna, long oClubId, List<DynaImage> images) {
        return createAbstractDyna(dyna,oClubId, DynaInfo.TYPE_ACTIVITY, images);
    }
}
